{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Data exploration workflow with diffprivlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import numpy as np\n",
    "import diffprivlib as dp\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data and differential privacy set-up"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We begin by initialising a `BudgetAccountant` to track the privacy spend of our exploration. By using the `set_default()` method, this accountant will be used by default in all diffprivlib calls."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc = dp.BudgetAccountant(1, 0)\n",
    "acc.set_default()\n",
    "\n",
    "# Our default epsilon value for this exploration\n",
    "eps = 0.04"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will use the Covertype dataset for this example. We can load is using `sklearn`. For the purpose of this exploration, we will use a numerical encoding of the \"Wilderness Area\" and \"Soil Type\" attributes. This will simplify visualisations later on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_covtype\n",
    "\n",
    "dataset = fetch_covtype()\n",
    "data, labels = dataset.data, dataset.target\n",
    "\n",
    "# Switch from one-hot encoding to numerical encoding for Wilderness Area and Soil Type\n",
    "data = np.concatenate((\n",
    "    data[:, :-44], \n",
    "    (data[:, -44:-40] * np.arange(0, 4)).sum(axis=1)[:, np.newaxis],\n",
    "    (data[:, -40:] * np.arange(0, 40)).sum(axis=1)[:, np.newaxis]\n",
    "), axis=1)\n",
    "\n",
    "n_examples = data.shape[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To assist our exploration, we will also specify the column names, and the ranges of each column. In this case, the ranges are assumed to be public knowledge, and therefore are not required to be calculated on the data. If the range is not known, it is common to search using a differentially private histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "col_names = [\"Elevation\", \"Aspect\", \"Slope\", \"H-Distance To Hydrology\", \n",
    "             \"V-Distance To Hydrology\", \"H-Distance To Roadways\", \n",
    "             \"Hillshade 9am\", \"Hillshade Noon\", \"Hillshade 3pm\", \n",
    "             \"H-Distance To Fire Points\", \"Wilderness Area\", \"Soil Type\"]\n",
    "\n",
    "ranges = [(1000.0, 4000.0), (0, 360), (0, 66), (0, 1000.0), (0, 1000.0),\n",
    "  (10, 10000.0), (0, 255), (0, 255), (0, 255), (10, 10000.0), (0, 3), (0, 39)]\n",
    "\n",
    "assert len(col_names) == len(ranges)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initial exploration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `histogram` function is a useful tool to visualise the data in a differentially private way. The syntax is the same as the corresponding function in NumPy, with the addition of an `epsilon` parameter. Also, to preserve differential privacy, we must specify the `range` of the histogram.\n",
    "\n",
    "In this first example, we plot the number of examples of each of the Covertype labels, 1‒7. The counts are not exact due to differential privacy, but give a good approximation of the true values. We can see that almost 50% of examples in the dataset are associated with the label \"2\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x252 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=(5,3.5))\n",
    "\n",
    "ax.bar(np.linspace(1, 7, 7), dp.tools.histogram(labels, epsilon=eps, bins=7, range=(1, 8))[0] / n_examples)\n",
    "ax.set_title(\"Label counts\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also plot the distribution of features in the dataset using `histogram`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1152x864 with 12 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axs = plt.subplots(3, 4, sharey=True, figsize=(16, 12))\n",
    "fig.subplots_adjust(hspace=0.35)\n",
    "\n",
    "for i in range(len(col_names)):\n",
    "    ax = axs.flat[i]\n",
    "    ax.set_title(col_names[i])\n",
    "    _range = ranges[i]\n",
    "    n_bins = 10\n",
    "    \n",
    "    # Wilderness Area and Soil Type need special config\n",
    "    if i >= 10:\n",
    "        _range = (0, _range[1] + 1)\n",
    "        n_bins = _range[1]\n",
    "\n",
    "    bar_width = (_range[1] - _range[0]) / n_bins * 0.9\n",
    "    \n",
    "    hist, bins = dp.tools.histogram(data[:, i], bins=n_bins, range=_range, epsilon=eps)\n",
    "    ax.bar(bins[:-1] + np.diff(bins), hist / n_examples, width=bar_width)\n",
    "    ax.set_ylim(0, 1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After our initial exploration, now is a good time to examine our budget spend, confirming that we have executed 13 queries thus far."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(epsilon=0.5199999999999999, delta=0.0)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.total()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "13"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(acc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Additional exploration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also use 2-dimensional histograms to extract more information in a differentially private way. In this example, we can plot the distribution of a feature with respect to each label."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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z/z58/nGN77BkiVLALjhhhs4++yzXzE0c/bs2ay//vosXLiQH/zgBxx55JF897vfBWDlypVceOGFHHrooQBcf/31fPnLX+a2227jzjvv5Kc//SmPPPIIn/vc57jyyiu54YYbmDhxIl/60pdadbiktuYQSkmSpEHsuuuu4+CDD2bIkCFsvvnmvP3tb2f+/Pnst99+HHfccTz//PNceumlTJ48mfXXX5/LL7+cm2++mYsuugiAJ554gj//+c8MHTqUXXfdtalnsI0ePZoRI0Zw44038uCDD7LzzjszYsQIAHbddVe23nprAA4++GCuu+46hg0bxm233cbb3vY2oEgoJ02a1KIjIrU3EzhJkqQBbvvtt38x4WrWsGHDmDJlCpdddhlz5sxhxowZQHE/3Ze//GX23Xffl20/b948Nthgg6bLP/roozn//PN54IEHOPLII19c3v1RABFBZrL33ntzwQUXrNE+SAORQyglSZIGuL322ovnn3+ec88998VlN998M9deey177rknc+bMYcWKFTz88MP85je/YddddwVg+vTpfPvb3+baa69l6tSpAOy777587WtfY9myZQD86U9/4plnnuk1hnXXXffFzwBMmzaNSy+9lPnz578sGbz++utZsmQJK1euZM6cOeyxxx7svvvu/Pa3v2Xx4sUAPPPMM/06g6bUTkzgJEmSBriI4Gc/+xlXXnkl22yzDdtvvz0nn3wyW2yxBdOmTWPHHXfkrW99K3vttRdnnnkmW2yxBQD77LMPv/71r3nXu97F0KFDgaLnbNy4cYwfP563vOUtfPSjH2X58uW9xjBz5kx23HFHDjnkEACGDh3KO97xDg466CCGDBny4na77LILxx57LGPHjmXMmDFMmzaNTTfdlPPPP5+DDz6YHXfckUmTJvHHP/6xBUdKan+RmXXH8DITJ07MBQsW1B2GpIpFxB8yc2LdcawN2ydp4BmobdPtt9/O2LFja4qoOStXrmT8+PH8+Mc/ZttttwWKYZhf+MIXuPjii/tcbifs+9r44vT3VF7mCXP6frzVGqtrm+yBkyRJUr+67bbbeOMb38g73/nOF5M3Sc1xEhNJkiT1q3HjxnHXXXe9YvmUKVOYMmVK/wckdRB74CRJkiSpQ9gDJ0mSJHWIYcOPrzsE1cweOEmSJEnqECZwkiRJktQhHEIpSZIkAEaf9MtKy7t79rt73ebII4/k4osvZrPNNuOWW26ptP6BaK95s1pQ6u0tKFOtYgInSZKk2hxxxBEce+yxHHbYYXWH0hEOOrn60/dFlZeoVnIIpSRJkmozefJkXvva19YdhtQxTOAkSZIkqUM0lcBFxNSIuCMiFkfEST2sPz4ibouImyPiqoh4Q8O6FRGxsPyZW2XwkiRJkjSY9DqINiKGAF8F9gaWAvMjYm5m3taw2Y3AxMz8e0R8DDgTmF6uezYzd6o4bkmSJEkadJrpgdsVWJyZd2XmC8CFwAGNG2TmNZn59/Lt74BR1YYpSZIkSWpmGpuRwL0N75cCu61m+6OAXzW8HxYRC4DlwOzM/PkaRylJkqSWa2ba/6odfPDBzJs3j0ceeYRRo0Zx6qmnctRRR/V7HFKnqHQe0og4FJgIvL1h8Rsy876I2Bq4OiIWZead3T43E5gJsNVWW1UZkiStFdsnSe1oILVNF1xwQd0hSB2lmQTuPmDLhvejymUvExHvAj4NvD0zn+9anpn3lf/eFRHzgJ2BlyVwmXkucC7AxIkTc812QZJax/ZJUjuybRq8Fi25p+4QVLNm7oGbD2wbEWMiYigwA3jZbJIRsTPwdeB9mflQw/LhEbFe+XoT4G1A4+QnkiRJkqQm9doDl5nLI+JY4DJgCHBeZt4aEacBCzJzLvCfwIbAjyMC4J7MfB8wFvh6RKykSBZnd5u9UpIkSZLUpKbugcvMS4BLui07peH1u1bxuf8BdlibACWpEy096dpKyxs1e89Ky5MkSZ2pqQd5S5IkSZLqZwInSZIkSR2i0scISJIkqYN9duOKy3ui103uvfdeDjvsMB588EEigpkzZ3LcccdVG4c0gJjASZIkqTbrrLMOX/ziFxk/fjxPPfUUEyZMYO+992bcuHF1hya1JYdQSpIkqTave93rGD9+PAAbbbQRY8eO5b77XvHIYUkle+AkqQXmLDmj0vJOwFkoJQ18d999NzfeeCO77bZb3aFIbcseOEmSJNXu6aef5oMf/CBnnXUWr371q+sOR2pbJnCSJEmq1bJly/jgBz/IIYccwgc+8IG6w5HamgmcJEmSapOZHHXUUYwdO5bjjz++7nCktuc9cJIkSSo0Me1/1X7729/yve99jx122IGddtoJgNNPP53999+/32OROoEJnCRJkmqzxx57kJl1hyF1DIdQSpIkSVKHMIGTJEmSpA5hAidJkiRJHcJ74CSpBYYNdyY1SZJUPXvgJEmSJKlDmMBJkiRJUodwCKUktcBe82ZVXOLtFZcnSa+0w3d2qLS8RYcv6nWb5557jsmTJ/P888+zfPlyDjzwQE499dRK45AGEhM4SZIk1Wa99dbj6quvZsMNN2TZsmXsscce7Lfffuy+++51hya1JYdQSpIkqTYRwYYbbgjAsmXLWLZsGRFRc1RS+7IHTpJa4KCTq21eex+EJEmda8WKFUyYMIHFixcza9Ysdtttt7pDGpSWnnRtpeWNmr1npeWpYA+cJEmSajVkyBAWLlzI0qVLuf7667nlllvqDklqWyZwkiRJaguvec1reMc73sGll15adyhS2zKBkyRJUm0efvhhHn/8cQCeffZZrrjiCt785jfXHJXUvrwHTpIkSUBz0/5X7f777+fwww9nxYoVrFy5koMOOoj3vOc9/R6H1ClM4CRJklSbHXfckRtvvLHuMKSOYQInSZIkiTlLzqi0vBNwFspW8B44SZIkSeoQTfXARcRU4GxgCPDNzJzdbf3xwNHAcuBh4MjM/Eu57nDg38pNP5eZ36kodkkalHxOjyRJg1evPXARMQT4KrAfMA44OCLGddvsRmBiZu4IXAScWX72tcBngN2AXYHPRMTw6sKXJEmSpMGjmR64XYHFmXkXQERcCBwA3Na1QWZe07D974BDy9f7Aldk5mPlZ68ApgIXrH3okiRJkqoybPjxdYegJjRzD9xI4N6G90vLZatyFPCrPn5WkiRJkrQKlc5CGRGHAhOBt6/h52YCMwG22mqrKkOSpLXS1/Zp0ZJ7WhWSs4RJatm50+1vHltZWQBj/3h709uuWLGCiRMnMnLkSC6++OJK46hDJ96vvNe8WRWX2Pz/v5rXTAJ3H7Blw/tR5bKXiYh3AZ8G3p6Zzzd8dkq3z87r/tnMPBc4F2DixInZREyS1C9snyS1o4HYNp199tmMHTuWJ598su5QBq2DTq72CWP9/1j4waGZIZTzgW0jYkxEDAVmAHMbN4iInYGvA+/LzIcaVl0G7BMRw8vJS/Ypl0mSJEkALF26lF/+8pccffTRdYcitb1e0+zMXB4Rx1IkXkOA8zLz1og4DViQmXOB/wQ2BH4cEQD3ZOb7MvOxiPh3iiQQ4LSuCU0kSZIkgE984hOceeaZPPXUU3WHIrW9pvpJM/MS4JJuy05peP2u1Xz2POC8vgYoSZKkgeviiy9ms802Y8KECcybN6/ucKS2V+1AV0mSJGkN/Pa3v2Xu3LlccsklPPfcczz55JMceuihfP/73687tLXihFNqFRM4SeowPqdH0kDy+c9/ns9//vMAzJs3jy984Qsdn7xJrWQCJ0mSJGDNpv2XVA8TOEmSJLWFKVOmMGXKlLrDGLRa+QxTVccETpI6zDmTjqu0vFk+qUeSKudwd7VKM8+BkyRJkiS1AXvgJEmSpIo5WkKtYg+cJEmSJHUIEzhJkiRJ6hAmcJIkSZLUIbwHTpIEwNKTrq28zFGz96y8TEmt89Vjrq60vFnn7NXUdqNHj2ajjTZiyJAhrLPOOixYsKDSOKSBxAROkiRJtbvmmmvYZJNN6g5DansOoZQkSZKkDmEPnCQJgDlLzqi8zBNwCKWk3kUE++yzDxHBRz/6UWbOnFl3SFLbMoGTJElSra677jpGjhzJQw89xN57782b3/xmJk+eXHdYa2XRknvqDkEDlEMoJUmSVKuRI0cCsNlmmzFt2jSuv/76miOS2pc9cJLUYbyqK2kgeeaZZ1i5ciUbbbQRzzzzDJdffjmnnHJK3WFJbcsETpIkSUDz0/5X6cEHH2TatGkALF++nA9/+MNMnTq13+OQOoUJnCQJgGHDj687BEmD0NZbb81NN91UdxhSx/AeOEmSJEnqEPbASZIAOGfScZWXOYtFlZcpSdJgZg+cJEmSJHUIEzhJkiRJ6hAmcJIkSZLUIUzgJEmSJKlDOImJJEmSAPji9PdUWt4Jcy5uarvHH3+co48+mltuuYWI4LzzzmPSpEmVxiINFCZwkiRJqtVxxx3H1KlTueiii3jhhRf4+9//XndIUtsygZMkSVJtnnjiCX7zm99w/vnnAzB06FCGDh1ab1BSGzOBW4WlJ11beZmjZu9ZeZmSJEmdbMmSJWy66aZ85CMf4aabbmLChAmcffbZbLDBBnWHJrWlpiYxiYipEXFHRCyOiJN6WD85Im6IiOURcWC3dSsiYmH5M7eqwCVJktT5li9fzg033MDHPvYxbrzxRjbYYANmz55dd1hS2+q1By4ihgBfBfYGlgLzI2JuZt7WsNk9wBHAJ3so4tnM3KmCWCVJLbRoyT11hyBpEBo1ahSjRo1it912A+DAAw80gZNWo5khlLsCizPzLoCIuBA4AHgxgcvMu8t1K1sQYy3mLDmj8jJPwCGUkiRJjbbYYgu23HJL7rjjDrbbbjuuuuoqxo0bV3dYUttqJoEbCdzb8H4psNsa1DEsIhYAy4HZmfnz7htExExgJsBWW221BkVXf6+a96lJarQ27ZMktUqr2qZmp/2v2pe//GUOOeQQXnjhBbbeemu+/e1v1xKH1An6YxKTN2TmfRGxNXB1RCzKzDsbN8jMc4FzASZOnJj9EJMkNcX2SVI7Gmht00477cSCBQvqDkPqCM0kcPcBWza8H1Uua0pm3lf+e1dEzAN2Bu5c7YfawLDhx9cdgiRJkiS9TDOzUM4Hto2IMRExFJgBNDWbZEQMj4j1ytebAG+j4d45SZIkSVLzeu2By8zlEXEscBkwBDgvM2+NiNOABZk5NyJ2AX4GDAfeGxGnZub2wFjg6+XkJq+iuAeu0gSu6slGnGhEkiRJUrtq6h64zLwEuKTbslMaXs+nGFrZ/XP/A+ywljHW4pxJx1Ve5iwWVV6mJEmSpMGjqQd5S5IkSZLqZwInSZIkSR2iPx4jIEmSpA5Qx/N177jjDqZPn/7i+7vuuovTTjuNT3ziE5XGIg0UHZ/A7X9Ta55IsGjJPS0pV5IkSS/ZbrvtWLhwIQArVqxg5MiRTJs2reaopPbV8QncQSdXuwtOMyJJ1avjqr6kznPVVVexzTbb8IY3vKHuUKS21fEJXCfyREaSJOmVLrzwQg4++OC6w5DampOYSJIkqXYvvPACc+fO5UMf+lDdoUhtzR44SVLLzVlyRqXlnYAjD6SB5le/+hXjx49n8803rzsUqa11fALnZCOSJEmd74ILLnD4pNSEjk/gOpFXoiUNNsOGH193CJKaUNd99c888wxXXHEFX//612upX+okJnCSJEmq1QYbbMCjjz5adxhSRzCBq4FXoiUNNudMOq7S8mb50BdJ0iDlLJSSJEmS1CHsgZMkSRqAMpOIqDuMfpWZdYegVfA5yNUxgavBXvNmVVzi7RWXJ0mSOtmwYcN49NFHGTFixKBJ4jKTRx99lGHDhtUditRSJnA1OOjkag+7d4JIkqRGo0aNYunSpTz88MN1h9Kvhg0bxqhRo+oOQz1wFvbqmMBJkiQNMOuuuy5jxoypOwxJLeAkJpIkSZLUIeyBkyS13KIl99QdgiRJA4IJnDRIOPuTJEmqi89Bro4JXA28Ei1JkqTBxFnYq2MCJ0mSJKmlnIW9Ok5iIkmSJEkdwh44aZDw+SuSJEmdzx44SZIkSeoQJnCSJEmS1CFM4CRJkiSpQ3gP3ABS9XO+wGd9DSQ+f0WSpM43+rkfVl7m3ZWX+Eo+Rqs6TSVwETEVOBsYAnwzM2d3Wz8ZOAvYEZiRmRc1rDsc+Lfy7ecy8ztVBC5pzZwz6bhKy5s1qCfwlSRJqkevQygjYgjwVWA/YBxwcESM67bZPcARwA+7ffa1wGeA3YBdgc9ExPC1D1uSJEmSBp9meuB2BRZn5l0AEXEhcABwW9cGmXl3uW5lt8/uC1yRma8ascgAAA+1SURBVI+V668ApgIXrHXkeoWqp4kHp4qXJEmS2kkzCdxI4N6G90spetSa0dNnR3bfKCJmAjMBttpqqyaLVnfe4yRVz/ZJUjuybZIGr7aYhTIzz83MiZk5cdNNN607HEl6ke2TpHZk2yQNXs30wN0HbNnwflS5rBn3AVO6fXZek5/VGtpr3qwWlHp7C8qUJEmS1BfNJHDzgW0jYgxFQjYD+HCT5V8GnN4wcck+wMlrHKWactDJ1T8VwnkGBw6n7+1fVU/zfHelpUmSpE7V6xl/Zi6PiGMpkrEhwHmZeWtEnAYsyMy5EbEL8DNgOPDeiDg1M7fPzMci4t8pkkCA07omNJEkaW35/EtJ0mDTVJdNZl4CXNJt2SkNr+dTDI/s6bPnAeetRYySJEmSJJpM4CRJakc+PkWSNNiYwEmSOpaPT5EkDTYmcFIb8X4eac2cM+m4ysuc5fRNkqQ2ZgI3gDjLoCRJkjSwmcBJbcT7eSRJUl18BE5neFXdAUiSJEmSmmMPnCSpYzl0XJI02JjASZIkaVBy8jB1IhM4qY04JbokSZJWxwROaiNOiS5JkqTVMYGTJEnSoOTsz+pEzkIpSZIkSR3CHjg1peqbfL3BV5Ik1c17z9WJ7IGTJEmSpA5hD5zURnymlSRJ/cfJw9SJTODUlF88vqzS8mZVWpo0uIx+7oeVlnd3paVJkqRWMoGTJEmSKubFNrWKCZyaUvUQA4cXSJIkSWvOSUwkSZIkqUPYAydJkqRBycnD1IlM4FQ7nzEnSZIkNcchlJIkSZLUIeyBU1NaOcTARxRIkiRJzen4BK5VU7RWXW5j2Xq5Tpzh0mGfGohs9yRJan8dn8BJdZiz5IxKyzsBEzhJkiT1zgRO6oNhw4+vOwRJLWZPuySpHZnASX3QicM+JUmS1PlM4FQ7n8EiqR3tN/bjlZa3yAs1kqQKNPUYgYiYGhF3RMTiiDiph/XrRcSccv3vI2J0uXx0RDwbEQvLn3OqDV+SJEmSBo9ee+AiYgjwVWBvYCkwPyLmZuZtDZsdBfwtM98YETOAM4Dp5bo7M3OniuOWelX1/Svw0j0s9hpKA5/fc0lSO2pmCOWuwOLMvAsgIi4EDgAaE7gDgM+Wry8CvhIRUWGc0hqr+vly4DPmJEmSVK9mEriRwL0N75cCu61qm8xcHhFPACPKdWMi4kbgSeDfMvMV3SIRMROYCbDVVlut0Q5Iq1L1RCPgZCODke2TpHZk2yQNXk3dA7cW7ge2ysydgeOBH0bEq7tvlJnnZubEzJy46aabtjgkSWqe7ZOkdmTbJA1ezfTA3Qds2fB+VLmsp22WRsQ6wMbAo5mZwPMAmfmHiLgTeBOwYG0DlyR1jtHP/bDS8u6utDRJkjpHMwncfGDbiBhDkajNAD7cbZu5wOHA/wUOBK7OzIyITYHHMnNFRGwNbAvcVVn0HcoTmf7hBAQv5++dJEmqi+ch1ek1gSvvaTsWuAwYApyXmbdGxGnAgsycC3wL+F5ELAYeo0jyACYDp0XEMmAlcExmPtaKHZEkSZI0uHxx+nsqL/OEORdXXmaVmnqQd2ZeAlzSbdkpDa+fAz7Uw+d+AvxkLWOUJEmSJNH6SUwkSZIkSRVpqgdOkiRJktrN+fv/pfIyT6i8xGrZAydJkiRJHcIeOKmNVD1DEwzuWZokSZIGGhM4SZL62dKTrq20vFGz96y0PElS+zKBkyR1rE7ttd5v7McrLW8RiyotT5LUvkzgBpBOPZGRpMFm0ZJ76g5BkgaEwdiemsBJkiSprTnsWHqJCZwkSZLa2pwlZ1Ra3gmYwKlzmcBJkiSprQ0bfnzdIUhtwwROkiRJbW2vebMqLvF2wPkD1JlM4CRJktTWDjq52lNW521VJ3tV3QFIkiRJkppjAidJkiRJHcIhlFIfVD1m/u5KS5NUBb/nUvsYjM/6klbFBE5N8URGktpf1c/KAp+XJUntxgROtTM5lKRqjBr2nhaU+kQLypQk9ZX3wEmSJElShzCBkyRJkqQOYQInSZIkSR3Ce+A0YFV9bx14f52kanjvryRVYzCe79kDJ0mSJEkdwh44SZLUq6ofUeDjCSSpb0zgJElSr6p/RIGPJxhovji92t+RE+Zc/OJrhx1LLzGBkyRpgBiM94KofQwbfnzdIUiDggmcJEmS1to5k46rtLxZLKq0PGlNtbJXeW2YwEmSpHp9duOKy3N4Zh0WLbmn7hCkSp2//18qLe+EisoxgZMkSb3yHqSBoerJaMAJaTRwtetFiaYSuIiYCpwNDAG+mZmzu61fD/guMAF4FJiemXeX604GjgJWAP+UmZdVFr0kSZKatt/Yj1de5iKHOkr9qtcELiKGAF8F9gaWAvMjYm5m3taw2VHA3zLzjRExAzgDmB4R44AZwPbA64ErI+JNmbmi6h2RJEmdyd69/tPKHgX/H6X+0UwP3K7A4sy8CyAiLgQOABoTuAOAz5avLwK+EhFRLr8wM58HlkTE4rK8/1tN+JIkSWqWM5VKzWvXixKRmavfIOJAYGpmHl2+/0dgt8w8tmGbW8ptlpbv7wR2o0jqfpeZ3y+Xfwv4VWZe1K2OmcDM8u12wB1rv2t9sgnwiHUPqvrd9/7zhszctB/rq0QbtU99Uffvd18Yc//oxJihNXHbNvWvTvzd67SYjbf1+iPmVbZNbTGJSWaeC5xbdxwRsSAzJ1r34Knffa9v3ztFu7RPfdGJ/8fG3D86MWbo3LhboVPbpk78P+y0mI239eqO+VVNbHMfsGXD+1Hlsh63iYh1gI0pJjNp5rOSJEmSpCY0k8DNB7aNiDERMZRiUpK53baZCxxevj4QuDqLsZlzgRkRsV5EjAG2Ba6vJnRJkiRJGlx6HUKZmcsj4ljgMorHCJyXmbdGxGnAgsycC3wL+F45ScljFEke5XY/opjwZDkwq81noKxzKMJgrbvu+t13DWSd+H9szP2jE2OGzo1bL+nE/8NOi9l4W6/WmHudxESSJEmS1B6aGUIpSZIkSWoDJnCSJEmS1CEGbQIXEXdHxKKIWBgRC8plr42IKyLiz+W/wyus77yIeKh8Zl7Xsh7ri8L/iYjFEXFzRIxvQd2fjYj7yv1fGBH7N6w7uaz7jojYdy3r3jIiromI2yLi1og4rlze8n1fTd39te/DIuL6iLiprP/UcvmYiPh9Wc+ccnIgysl+5pTLfx8Ro1tQ9/kRsaRh33cql1f6O6fWq/O7VUHsQyLixoi4uHzf8u9EBTG/JiIuiog/RsTtETGp3Y91RPxz+btxS0RcULYLbXWso6K/jRFxeLn9nyPi8J7qUj2in8+3+hBfbednFcfcL+c2fYy3o/5erSbe9jnGmTkofygehr5Jt2VnAieVr08CzqiwvsnAeOCW3uoD9gd+BQSwO/D7FtT9WeCTPWw7DrgJWA8YA9wJDFmLul8HjC9fbwT8qayj5fu+mrr7a98D2LB8vS7w+3KffgTMKJefA3ysfP1x4Jzy9QxgTgvqPh84sIftK/2d86f1P3V+tyqI/Xjgh8DF5fuWfycqiPk7wNHl66HAa9r5WAMjgSXA+g3H+Ih2O9ZU8LcReC1wV/nv8PL18Lp+V/x5xf/x3fTj+VYf4qvt/KzimD9LP5zb9DHejvp7tZp42+YYD9oeuFU4gOKPNOW/76+q4Mz8DcUMnc3UdwDw3Sz8DnhNRLyu4rpX5QDgwsx8PjOXAIuBXdei7vsz84by9VPA7RQnFi3f99XUvSpV73tm5tPl23XLnwT2Ai4ql3ff965jchHwzoiIiutelUp/59R6dX631kZEjALeDXyzfB/0w3dibUTExhQnTN8CyMwXMvNx2vxYU8w0vX4Uz2f9B+B+2uxYV/S3cV/gisx8LDP/BlwBTG117ForLTvfWlN1np/1VZ3ndX3RaX+v6j5/bMZgTuASuDwi/hARM8tlm2fm/eXrB4DNWxzDquobCdzbsN1SVv+L01fHll3T5zUMX2hZ3eWQnJ0peoP6dd+71Q39tO9RDBVbCDxEcVJxJ/B4Zi7voY4X6y/XPwGMqKruzOza9/8o9/2/ImK97nX3EJfaXJ3frT44C/gXYGX5fgT99J1YC2OAh4FvRzH085sRsQFtfKwz8z7gC8A9FInbE8AfaP9jDWt+XGs/3lqtdjjfWlNt+93uRb+e1/VFh/29qu38sTeDOYHbIzPHA/sBsyJicuPKLPpE++0ZC/1dH/A1YBtgJ4o/7l9sZWURsSHwE+ATmflk47pW73sPdffbvmfmiszcCRhFcTXmza2qq7e6I+ItwMllDLtQDDf61/6KR61R53drTUXEe4CHMvMPdceyhtahGK70tczcGXiGYrjPi9rwWA+nuCo8Bng9sAEd2CvVbsdVfdJW51trqt3ja9Cv53V90Ul/r6De88feDNoErrw6SWY+BPyM4uT6wa4u2vLfh1ocxqrquw/YsmG7UeWyymTmg+UJ/krgG7zU1Vt53RGxLsUX4AeZ+dNycb/se0919+e+dymHW10DTKIYCrBOD3W8WH+5fmPg0QrrnloOC8jMfB74Nv2w72qdOr9bffQ24H0RcTdwIcVwvrPp5+9EHywFljb0Yl9EkdC187F+F7AkMx/OzGXATymOf7sfa1jz49oOx1ur0CbnW2uqnb/bParj3GZNdNrfq3Y5f1yVQZnARcQGEbFR12tgH+AWYC7QNXvV4cAvWhzKquqbCxxWzsKzO/BEQxdzJbqNJZ5Gsf9ddc+IYkayMcC2wPVrUU9Q3Ddye2Z+qWFVy/d9VXX3475vGhGvKV+vD+xNMY76GuDAcrPu+951TA4Eri6vSFVV9x8bGsqgGGveuO8t/Z1Tter8bvVVZp6cmaMyczTFRBlXZ+Yh9MN3Ym1k5gPAvRGxXbnoncBttPGxphg6uXtE/EP5u9IVc1sf6x5iaea4XgbsExHDy57HfcplqlkbnW+tqXb+bveov85t+hhbR/29qvv8sSnZj7O6tMsPsDXFbDE3AbcCny6XjwCuAv4MXAm8tsI6L6Dobl1GcTX3qFXVRzHrzlcp7pdaBExsQd3fK8u+meIX73UN23+6rPsOYL+1rHsPii7xm4GF5c/+/bHvq6m7v/Z9R+DGsp5bgFMafv+up7jJ9cfAeuXyYeX7xeX6rVtQ99Xlvt8CfJ+XZqqs9HfOn9b/1Pndqij+Kbw0C2XLvxMVxLsTsKA83j+nmO2wrY81cCrwx/L7/j2KGdLa6lhT0d9G4Mgy9sXAR+r83fbnZf+//X6+1YcYazs/qzjmfjm36WO8HfX3ajXxts0xjrJSSZIkSVKbG5RDKCVJkiSpE5nASZIkSVKHMIGTJEmSpA5hAidJkiRJHcIETpIkSZI6hAmcJEmSJHUIEzhJkiRJ6hD/P+AbNqqFXGNKAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 1080x288 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axs = plt.subplots(1, 3, figsize=(15, 4), sharey=True)\n",
    "n_bins = 10\n",
    "\n",
    "# Columns of the dataset we want to plot\n",
    "cols = (1, 3, 8)\n",
    "\n",
    "for _i, col in enumerate(cols):\n",
    "    ax = axs.flat[_i]\n",
    "    ax.set_title(col_names[col])\n",
    "    width = (ranges[col][1] - ranges[col][0]) / n_bins * 0.9\n",
    "\n",
    "    hist, bins, _ = dp.tools.histogram2d(data[:, col], labels, epsilon=eps, bins=(n_bins, 7), \n",
    "                                             range=(ranges[col], (1, 8)))\n",
    "    cum_sum = np.zeros_like(hist[:, 0])\n",
    "\n",
    "    for i in range(hist.shape[1]):\n",
    "        ax.bar(bins[:-1] + np.diff(bins), hist[:, i] / n_examples, bottom=cum_sum, label=str(i+1), width=width)\n",
    "        cum_sum += hist[:, i] / n_examples\n",
    "        \n",
    "ax.legend(title=\"Cover type\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With some extra effort, we can also produce 2-dimensional histograms to show correlation between features."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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mjVr8uKLL/rU/8jISBo2bEjNmjVp164dR48eTbZ+aGgoBQsW5OjRo6gqgwcPpnr16tSoUYPZs2cDJLlNAK+88gqVKlWiUaNG7Ny5E4BDhw5Rt25dALZs2YKI8PvvvwNw8803c/r0ab788ksaNGhA7dq1ueuuu/jzzz+5dOkSoaGhxMbGAnDp0iVCQkKIjY1l7ty5VK9enVq1atG4cWMCwQKoMa4zZ854DmnDwsIYNmxYyo1c1113HRUrViQqKipe+YQJExgwYACRkZFs3LiRcuXKMWrUKG6++WYiIyN54403KFCgAF988QWbN29mxYoVPP3003GvISYqKop+/fqxbds2rr/+eubPnw9A165d6devH1u2bOGHH36gTJkyLFu2jKioKNavX09kZCSbNm1i1apVV/Q1oe7du/P666/z008/UaNGDUaMGJFs/c2bNxMaGkrJkiX5/PPPiYyMZMuWLXzzzTcMHjyYgwcPJrlNmzZtYtasWURGRrJ48WI2bNgAQMmSJfn77785ceIEq1evJjw8nNWrV/Pbb79RsmRJChYsSKNGjVi7di0//vgjXbp0YfTo0eTKlYtu3boxc6bzfrxvvvmGWrVqUaJECUaOHMnSpUvZsmULixYF5mHGqyaZiDFpdc011xAZGen5HneY66vEcuveeuutvPLKK8TExNC+fXtCQ0MTbffcc8+xatUqcuXKxf79+/nzzz8BqFixImFhzgN5devWJTo6mpMnT7J//37atWsHODeAAyxbtoxly5ZRu7Zzw8qpU6eIiopKdvR1/Phxjh07xh133AFAjx496NixY6J13377bT755BN+/fVXvvzySwC+//577r//fnLnzk2pUqW444472LBhA61atUp0m1avXk27du0oWLAgABEREZ7l/+Mf/+C///0vq1at4rnnnmPJkiWoKrff7rw5OiYmhs6dO3Pw4EHOnTvnuV+zd+/etG3blieffJLJkyfTq1cvAG677TZ69uxJp06daN++fZL7IC1sBGpMCi5evJjiqPTkyZNER0dTqVKleOUPPPAAixYt4pprrqF169YsX37lefeZM2cSGxvLpk2biIyMpFSpUp4LUvnz5/fUy507NxcuXEiyn6rKs88+S2RkJJGRkezatYs+ffr4s8mJGjhwINu2bWP+/Pn06dMn2Xsmk9umpDRu3Ngz6mzbti1btmzh+++/9wTQJ554gscff5yff/6ZiRMnepZ34403UqpUKZYvX8769etp1cp5U/eECRN4+eWX2bdvH3Xr1uXw4cPptCcuswBqTApy587tCUojR468Yv6pU6d47LHHuO+++wgKCoo3b8+ePdx0003079+ftm3b8tNPP1G4cGFOnjzpqXP8+HFKlixJ3rx5WbFiBb/9lmT2NAAKFy5MuXLlWLDAeTjv7NmznD59mpYtWzJ58mROnToFwP79+zl06FByi6JIkSIEBQWxevVqAKZPn+4ZjSYlIiKC8PBwpk6dyu23387s2bO5ePEisbGxrFq1ivr16ye5TY0bN2bBggWcOXOGkydPekayALfffjszZswgNDSUXLlyUbRoURYvXkyjRo08+6ls2bIATJ06NV6fHnroIbp160bHjh3JnTs3ALt376ZBgwaMHDmSEiVKsG/fPtKbHcIb46cmTZqgqly6dIl27doxdOjQK+rMmTOH6dOnkzdvXkqXLs1zzz1H0aJFue2226hevTqtWrXimWeeoU2bNtSoUYPw8HBuueWWFNc9ffp0HnnkEYYNG0bevHmZO3cuLVq0YMeOHdx6662Ac3FrxowZlCxZMtllTZ06lUcffZTTp09z00038cknn6S4/mHDhvHAAw+wfft21qxZQ61atRARRo8eTenSpenatWui21SnTh06d+5MrVq1KFmyJPXq1fMsMzg4GFX1nHJo1KgRMTExnv+Uhg8fTseOHQkKCqJp06bs3bvX0zYiIoJevXp5Dt8BBg8eTFRUFKpKs2bNqFWrVorblVpXzTuRwsPDNbUJle02ppxhx44dVKlSJbO7YQJo48aNDBw40DOS9ldif1dEZJP7WPkVbARqjMnWRo0axQcffOC5Ep+R7ByoMSZbGzJkCL/99pvnXGlGsgBqjDF+sgBqjDF+sgBqjDF+sgBqjDF+sqvwJscJHvJVui4vetQ96bq8lBw+fJgOHTqwYcMGevbsGS+j0qZNm+jZsydnzpyhdevWvPvuu4gIR44coXPnzkRHRxMcHMycOXMICgpCVRkwYACLFy+mYMGCTJkyhTp16mTo9mRnNgI1JpOcO3eOv/76K9XtChQowEsvvZRoHs2+ffvy0UcfERUVRVRUFEuWLAGcW32aNWtGVFQUzZo1Y9SoUQB8/fXXnroffvghffv2TdtG5TAWQI3JYDt27ODpp5+mcuXK/Prrr6luf+2119KoUSNPEpE4Bw8e5MSJEzRs2BARoXv37p7HPRcuXEiPHj0AJ2GId3n37t0RERo2bMixY8c4ePBgGrcw57BDeGMywF9//cWcOXP4+OOPAejVqxfDhw+ncOHCgJOoY8WKFVe069KlC0OGDPFpHfv376dcuXKe7+XKlWP/fuc1ZH/++SdlypQBoHTp0p5sT/v37+fGG2+8ok1cXZM8C6DGZIAyZcpQs2ZNJk2alOiz7m+//XaG9UVE7CV76cQO4Y3JAPPmzaNs2bK0b9+ekSNHXpFxaeDAgfGSOcd94s5V+qJs2bLExMR4vsfExHiyF5UqVcpzaH7w4EFPgpGyZcvGy1Lk3cakzAKoMRmgRYsWzJ49m9WrV1OkSBHatm3LXXfd5XmZ29tvv+1Jmef98fXwHZxR7nXXXcfatWtRVaZNm0bbtm0BJ1tRXAq4qVOnxiufNm0aqsratWspUqSIHb6ngh3Cmxwno2878lasWDEGDBjAgAEDWL9+vSd3ZWoFBwdz4sQJzp07x4IFC1i2bBlVq1Zl/PjxntuYWrVq5UkuPGTIEDp16sTHH39MhQoVmDNnDgCtW7dm8eLFhISEULBgQZ9S2ZnLLIAak0nq16/vd9ukXkMcHh7O1q1brygvVqwY33777RXlIsK4ceP87kdOZ4fwxhjjJwugxhjjJwugxhjjJwugxhjjJwugxhjjJwugxhjjJwugJucZXiR9P+ls7ty5VKtWjVy5cpHwTbOvvfYaISEhVK5cmaVLl3rKlyxZQuXKlQkJCYn39NLevXtp0KABISEhdO7cmXPnziW6zi+//JKqVatSvXp1nn/++Svmf/TRR1SuXJlq1aoxfvz4dNrSlHXt2pXKlStTvXp1evfuzfnz5wFQVfr3709ISAg1a9Zk8+bNnjZTp04lNDSU0NDQeO+P37RpEzVq1CAkJIT+/fuTHm8ktgBqTAY4evSoz3WrV6/O559/7nk/epzt27cza9Ystm3bxpIlS3jssce4ePEiFy9epF+/fnz99dds376dzz77jO3btwPwzDPPMHDgQHbt2kVQUJAnmUlCTz75JF999RVbt27loYceijfvwoULPP/882zYsIGtW7dyzz2pfxDhyJEjqW4DTgD95Zdf+Pnnnzlz5gyTJk0Ckk7Dd+TIEUaMGMG6detYv349I0aM8Oz7pFL9pUWOvpG+6cp+AVz6jgAu22Q34eHhNGzYkD59+tCkSZNkk3kk9Q77hQsX0qVLF/Lnz0/FihUJCQlh/fr1AISEhHDTTTcBTganhQsXUqVKFZYvX86nn34KOGnshg8fnmjOz3z58hETE0PFihWpWLHiFfMvXLjA4cOHue6666hQoYJP2/z3338zf/58Jk2aRNmyZZkxY4ZP7by1bt3aM12/fn3Ps/5JpeFbuXIlzZs3p2jRogA0b96cJUuWcOedd3pS/QGeVH9xT2r5y0agxmSAX3/9lfvvv5+xY8dStWpVXn31VQ4cOJCqZSSVei6p8sOHD3P99deTJ0+eeOUJXbp0iapVq9K7d+9En3C6cOECtWrV4r777vNpJLllyxaeeOIJqlevzpo1a3jrrbc8wXPnzp2JJk0JCwvj2LFjSS7z/PnzTJ8+nbvvvtuvfZFcqr+0yNEj0Iwy7tHlAVt2vwlNA7Zsk35y587Nvffey7333ktsbCzPPvss5cuX54cffkjTI53p4f3336dWrVr07duXNm3asHz5cqKjo3n99deZN28ezz77LL169QKc5CPLli3jq6++Yt26dVdkxR8zZgzPPfccb7zxBm+++Sb58+ePN79y5cpERkamuo+PPfYYjRs35vbbb/d/QwMgoAFURO4G3gVyA5NUdVSC+U8BDwEXgFigt6r+5s7rAbzgVn1ZVadiTDZ2/PhxZs2axZQpU8iXLx+TJ0+mZs2aPrdPLvVcYuXFihXj2LFjXLhwgTx58iSZqm7p0qX861//4s4772To0KHcc8891K9fny5dunjmDxgwgODgYA4dOkTHjh259tprGTx48BXL6tatG+fPn2fixImsWLGCXr160apVK88oeOfOnXTu3DnR7Vu5ciXXX3/9FeUjRowgNjaWiRMnprgvypYty8qVK+OV33nnncmm+kuLgB3Ci0huYBzQCqgK3C8iVRNU+xEIV9WawDxgtNu2KPAi0ACoD7woIkGB6qsxgdatWzfq1KnD3r17mTZtGt999x3du3e/4rUcyYmIiGDWrFmcPXuWvXv3EhUVRf369alXrx5RUVHs3buXc+fOMWvWLCIiIhARmjRpwrx584D4aey81a5dmxkzZnDp0iU6depEaGgon376qediUe3atZk2bRoATz31FCdPnmTbtm3UrVv3imWVLFmSZ555hq1bt/Lk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\n",
      "text/plain": [
       "<Figure size 360x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=(5, 4))\n",
    "col1, col2 = (3, 5)\n",
    "\n",
    "n_bins = 10\n",
    "\n",
    "ax.set_title(col_names[col1] + \" v \\n\" + col_names[col2])\n",
    "width = (ranges[col1][1] - ranges[col1][0]) / n_bins * 0.9\n",
    "\n",
    "hist, bins, _ = dp.tools.histogram2d(\n",
    "    data[:, col1], \n",
    "    (data[:, col2] > 1000).astype(int) + (data[:, col2] > 2000) + (data[:, col2] > 3000) + (data[:, col2] > 4000), \n",
    "    epsilon=eps, bins=(n_bins, 5), range=(ranges[col1], (0, 5))\n",
    ")\n",
    "legends = [\"<= 1000\", \"> 1000 && <= 2000\", \"> 2000 && <= 3000\", \"> 3000 && <= 4000\", \"> 4000\"]\n",
    "\n",
    "cum_sum = np.zeros_like(hist[:, 0])\n",
    "\n",
    "for i in range(hist.shape[1]):\n",
    "    ax.bar(bins[:-1] + np.diff(bins), hist[:, i] / n_examples, bottom=cum_sum, label=legends[i], width=width)\n",
    "    cum_sum += hist[:, i] / n_examples\n",
    "\n",
    "ax.set_xlabel(col_names[col1])\n",
    "ax.set_ylabel(\"Frequency\")\n",
    "ax.legend(title=col_names[col2])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Colour maps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also use the 2-dimensional histogram to plot colour maps of the data. This allows us to examine correlations between features."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "col1, col2 = (1, 3)\n",
    "\n",
    "hist, bins_y, bins_x = dp.tools.histogram2d(data[:, col1], data[:, col2], epsilon=eps, \n",
    "                                            range=(ranges[col1], ranges[col2]))\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(5, 4))\n",
    "c = ax.pcolormesh(bins_y, bins_x, hist / n_examples, cmap='Blues')\n",
    "ax.set_ylabel(col_names[col1])\n",
    "ax.set_xlabel(col_names[col2])\n",
    "fig.colorbar(c, ax=ax)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Other queries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Diffprivlib includes a number of simple statistical functions to examine the data in more detail. These include `mean`, `var`, `sum` and `count_nonzero` functions.  They can be useful in querying more specific information than can be portrayed by histograms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2959.413492430157"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.mean(data[:, 0], bounds=ranges[0], epsilon=eps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "76507.10941871432"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.var(data[:, 0], bounds=ranges[0], epsilon=eps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`count_nonzero` is useful for counting more specific information than is required from a histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.49394160533689496"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.count_nonzero(data[:, 0] >= 3000, epsilon=eps) / n_examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also get label-specific information by indexing the `data` array appropriately."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3128.5443965699988"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.mean(data[labels==1, 0], bounds=ranges[0], epsilon=eps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Total privacy loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Having completed our initial exploration, we can compute the total privacy loss from the accountant."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(epsilon=0.8800000000000002, delta=0.0)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.total()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And we can also compute the remaining budget to be spent on subsequent queries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(epsilon=0.11999999999999988, delta=0.0)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.remaining()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
